package pers.hl.lib_global.service

import okhttp3.MultipartBody
import pers.hl.lib_global.common.Const.RequestParam.PARAM_PAGE_NUM
import pers.hl.lib_global.common.Const.RequestParam.PARAM_PAGE_SIZE
import pers.hl.lib_global.http.LibResponse
import pers.hl.lib_global.model.bean.*
import retrofit2.http.*
import java.io.File

interface LibService {

    /**
     * 豆瓣api
     */
    @GET
    suspend fun getDouBanBook(@Url url: String): LibResponse<*>

    /**
     * 登录
     * @param  username 账号 password 密码
     * @return
     */
    @POST("user/login")
    suspend fun login(
        @Query("account") userName: String,
        @Query("password") passWord: String
    ): LibResponse<User>

    /**
     * 注册
     * @param  username 账号 password 密码
     * @return
     */
    @POST("user/sign_up")
    suspend fun register(
        @Query("account") userName: String,
        @Query("password") passWord: String
    ): LibResponse<User>

    /**
     * 获取所有书籍标签
     */
    @GET("bookTag/list/all")
    suspend fun allBookTags(): LibResponse<List<BookTag>>

    /**
     * 获取所有书籍
     */
    @GET("book/listByKey/all")
    suspend fun allBooks(): LibResponse<List<Book>>

    /**
     * 根据标签id获取分类下的书籍列表
     */
    @GET("book/list/tagId/{otherId}")
    suspend fun getBooksByTag(@Path("otherId") tagId: Int): LibResponse<List<Book>>

    /**
     * 获取借阅前5的书籍
     */
    @GET("book/top5")
    suspend fun getTop5Books(): LibResponse<List<Book>>

    /**
     * 搜索接口（老）
     */
    @GET("book/search")
    suspend fun searchBooks(@Query("keywords") content: String): LibResponse<List<Book>>

    /**
     * 搜索接口（新）
     */
    @GET("book/listByKey/search/{keywords}")
    suspend fun searchBooksNew(
        @Path("keywords") content: String,
        @Query(PARAM_PAGE_SIZE) pageSize: Int,
        @Query(PARAM_PAGE_NUM) pageNum: Int
    ): LibResponse<List<Book>>

    /**
     * 获取用户持有书籍列表
     */
    @GET("book/listByKey/userId/{value}")
    suspend fun getUserBooks(@Path("value") userId: Int): LibResponse<List<Book>>

    /**
     * 新增图书馆（仅管理员）
     */
    @POST("lib/add")
    suspend fun addLibrary(@Body library: Library): LibResponse<Library>

    /**
     * 获取所有图书馆（仅管理员）
     */
    @GET("lib/listByKey/all/any")
    suspend fun getAllLibraries(@Query("pageNum") pageNum: Int): LibResponse<List<Library>>

    /**
     * 批量删除图书馆
     *
     * 出现异常：java.lang.IllegalArgumentException: Non-body HTTP method cannot contain @Body.
     * 对于delete方式来讲有以下区别：
     * @DELETE("/job/deletejob") // For DELETE without body
     * @HTTP(method = "DELETE", path = "/job/deletejob", hasBody = true) // For DELETE with body
     */
    @HTTP(method = "DELETE", path = "lib/delete", hasBody = true)
    suspend fun deleteLibrary(@Body delIds: List<Int>): LibResponse<*>

    /**
     * 根据关键词（名称/位置）搜索图书馆信息
     */
    @GET("lib/listByKey/search/{keyword}")
    suspend fun searchLibrary(@Path("keyword") keyword: String): LibResponse<List<Library>>

    /**
     * 更新图书馆信息
     */
    @POST("lib/update")
    suspend fun updateLibrary(@Body library: Library): LibResponse<*>

    /**
     * 查询所有书籍
     */
    @GET("book/listByKey/all/any")
    suspend fun getAllBooks(): LibResponse<List<Book>>

    /**
     * 批量删除图书
     */
    @HTTP(method = "DELETE", path = "book/delete", hasBody = true)
    suspend fun deleteBooks(@Body bookIds: List<Int>): LibResponse<*>

    /**
     * 批量删除标签
     */
    @HTTP(method = "DELETE", path = "bookTag/delete", hasBody = true)
    suspend fun deleteTags(@Body ids: List<Int>): LibResponse<*>

    /**
     * 更新标签信息
     */
    @POST("bookTag/update")
    suspend fun updateTag(@Body tag: BookTag): LibResponse<*>

    /**
     * 添加书籍标签
     */
    @POST("bookTag/add")
    suspend fun addTag(@Body tag: BookTag): LibResponse<*>

    /**
     * 批量删除用户
     */
    @HTTP(method = "DELETE", path = "user/delete", hasBody = true)
    suspend fun deleteUsers(@Body ids: List<Int>): LibResponse<*>

    /**
     * 获取所有用户
     */
    @GET("user/listByKey/all/any")
    suspend fun getAllUsers(): LibResponse<List<User>>

    /**
     * 更新用户信息
     */
    @POST("user/update")
    suspend fun updateUser(@Body user: User): LibResponse<*>

    /**
     * 修改书籍
     */
    @POST("book/update")
    suspend fun changeBookStatus(@Body book: Book): LibResponse<*>

    /**
     * 添加书籍
     */
    @POST("book/add")
    suspend fun addBook(@Body book: Book): LibResponse<*>

    /**
     * 查询附近图书馆
     * 默认1000m范围，自定义范围增加 distance 参数 Double
     */
    @GET("lib/nearby")
    suspend fun fetchNearByLibraries(
        @Query("latitude") latitude: Double,
        @Query("longitude") longitude: Double
    ): LibResponse<List<Library>>

    /**
     * 根据id查找书籍
     */
    @GET("book/{id}")
    suspend fun fetchBookById(@Path("id") id: Int): LibResponse<Book>

    /**
     * 查询我的借阅书籍（包括借阅中和已借阅）
     */
    @GET("book/myBorrows")
    suspend fun fetchMyBorrows(): LibResponse<List<BookBorRec>>

    /**
     * 查询我的借阅书籍（已借阅）
     */
    @GET("book/myBorrowed")
    suspend fun fetchMyBorrowed(): LibResponse<List<BookBorRec>>

    /**
     * 发起借阅
     */
    @POST("book/borrow/{bookId}")
    suspend fun borrow(@Path("bookId") bookId: Int): LibResponse<*>

    /**
     * 取消借阅
     */
    @POST("book/cancel/{recordId}")
    suspend fun cancel(@Path("recordId") recordId: Int): LibResponse<*>

    /**
     * 接受借阅
     */
    @POST("book/accept/{recordId}")
    suspend fun accept(@Path("recordId") recordId: Int): LibResponse<*>

    /**
     * 拒绝借阅
     */
    @POST("book/refuse/{recordId}")
    suspend fun refuse(@Path("recordId") recordId: Int): LibResponse<*>

    /**
     * 归还图书
     */
    @POST("book/return/{recordId}")
    suspend fun returnBack(@Path("recordId") recordId: Int): LibResponse<*>

    /**
     * 用户的分享（当前存在借阅记录并且借阅状态为已借阅(已接受)、已归还状态的书籍分享记录）
     */
    @GET("book/sharing")
    suspend fun userShare(@Query("userId") userId: Int): LibResponse<List<BookShareRec>>

    /**
     * 我的发布
     */
    @GET("book/myPublish")
    suspend fun fetchUserPublish(): LibResponse<List<BookShareRec>>

    /**
     * 获取书籍评论
     */
    @GET("comment/list/bookId/{bookId}")
    suspend fun getBookComments(@Path("bookId") bookId: Int): LibResponse<List<Comment>>

    /**
     * 获取书籍详情
     */
    @GET("book/{bookId}")
    suspend fun getBookInfo(@Path("bookId") bookId: Int): LibResponse<Book>

    /**
     * 添加评论
     */
    @POST("comment/add")
    suspend fun addComment(@Body comment: Comment): LibResponse<*>

    /**
     * 删除评论
     */
    @HTTP(method = "DELETE", path = "comment/delete", hasBody = true)
    suspend fun deleteComment(@Body ids: List<Int>): LibResponse<*>

    /**
     * 添加回复
     */
    @POST("reply/add")
    suspend fun addReply(@Body reply: Reply): LibResponse<*>

    /**
     * 获取评论下的回复列表
     */
    @GET("reply/list/cmtId/{cmtId}")
    suspend fun fetchReplyListByCmtId(@Path("cmtId") cmtId: Int): LibResponse<List<Reply>>

    /**
     * 收藏书籍
     */
    @POST("book/collect/{bookId}")
    suspend fun collect(@Path("bookId") bookId: Int): LibResponse<*>

    /**
     * 取消收藏
     */
    @POST("book/uncollect/{bookId}")
    suspend fun uncollect(@Path("bookId") bookId: Int): LibResponse<*>

    /**
     * 我的收藏书籍
     */
    @GET("book/myCollect")
    suspend fun myCollectBook() : LibResponse<List<Book>>

    /**
     * 我的评论
     */
    @GET("comment/list/userId/{userId}")
    suspend fun myComments(@Path("userId") userId: Int): LibResponse<List<Comment>>

    /**
     * 我的收藏记录
     */
    @GET("collect/list/userId/{userId}")
    suspend fun myCollect(@Path("userId") userId: Int): LibResponse<List<Collect>>

    /**
     * 获取用户关注
     */
    @GET("user/list/follows/{userId}")
    suspend fun userFollows(@Path("userId") userId: Int): LibResponse<List<User>>

    /**
     * 获取用户粉丝
     */
    @GET("user/list/fans/{userId}")
    suspend fun userFans(@Path("userId") userId: Int): LibResponse<List<User>>

    /**
     * 获取用户信息
     */
    @GET("user/{userId}")
    suspend fun userInfo(@Path("userId") userId: Int): LibResponse<User>

    /**
     * 检查是否关注
     */
    @GET("follow/isFollow")
    suspend fun isFollowed(@Query("followerId") followerId: Int, @Query("userId") userId: Int): LibResponse<Boolean>

    /**
     * 关注
     */
    @POST("follow/add")
    suspend fun follow(@Body followRec: FollowRec): LibResponse<*>

    /**
     * 取消关注
     */
    @HTTP(method = "DELETE", path = "follow/unfollow", hasBody = true)
    suspend fun unFollow(@Query("followerId") followerId: Int, @Query("userId") userId: Int): LibResponse<*>

    /**
     * 扫码借阅
     */
    @POST("book/scanBorrow/{bookId}")
    suspend fun scanBorrow(@Path("bookId") bookId: Int): LibResponse<*>

    /**
     * 文件上传
     * @param file 文件
     * @param bussId 业务主键id
     * @param fileType 文件类型
     */
    @POST("file/upload")
    @Multipart
    suspend fun uploadFile(
        @Part file: MultipartBody.Part,
        @Query("fileBussId") bussId: Int,
        @Query("fileType") fileType: Int
    ): LibResponse<FileEntity>

    /**
     * 获取图书馆下的书籍
     */
    @GET("book/listByKey/libId/{libId}")
    suspend fun getBookByLibId(@Path("libId") libId: Int) : LibResponse<List<Book>>

    /**
     * 检查是否存在即将到期的借阅（距离到期时间<=5天）
     */
    @GET("book/checkExpiringRecord")
    suspend fun checkExpiringRecord(): LibResponse<List<BookBorRec>>
}